package com.demo2.todo.service.impl;

import com.demo2.todo.model.entity.Tag;
import com.demo2.todo.model.entity.Todo;
import com.demo2.todo.model.entity.User;
import com.demo2.todo.model.enums.TodoStatus;
import com.demo2.todo.repository.TagRepository;
import com.demo2.todo.repository.TodoRepository;
import com.demo2.todo.service.TodoImportExportService;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * @author evi
 */
@Service
@RequiredArgsConstructor
public class TodoImportExportServiceImpl implements TodoImportExportService {
    private final TodoRepository todoRepository;
    private final TagRepository tagRepository;

    // 导出为Excel
    // 导出增加标题和到期时间
    @Override
    @Transactional(readOnly = true)
    public ByteArrayResource exportTodos(List<Todo> todos) {
        try (Workbook workbook = new XSSFWorkbook();
             ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            Sheet sheet = workbook.createSheet("Todos");

            // 创建表头
            Row headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("ID");
            headerRow.createCell(1).setCellValue("标题");
            headerRow.createCell(2).setCellValue("内容");
            headerRow.createCell(3).setCellValue("状态");
            headerRow.createCell(4).setCellValue("创建时间");
            headerRow.createCell(5).setCellValue("到期时间");
            headerRow.createCell(6).setCellValue("标签");

            // 填充数据
            for (int i = 0; i < todos.size(); i++) {
                Todo todo = todos.get(i);
                Row row = sheet.createRow(i + 1);
                row.createCell(0).setCellValue(todo.getId() != null ? todo.getId() : 0);
                row.createCell(1).setCellValue(todo.getTitle());
                row.createCell(2).setCellValue(todo.getContent());
                row.createCell(3).setCellValue(todo.getStatus().name());
                row.createCell(4).setCellValue(todo.getCreatedAt().toString());
                row.createCell(5).setCellValue(todo.getDeadline() != null ? todo.getDeadline().toString() : "");

                // 导出标签
                // 假设你在 Service 或工具类中已获取到标签 ID 列表
                List<Long> tagIds = tagRepository.findTagIdsByTodoId(todo.getId());

                // 通过 ID 列表查询标签名称
                List<String> tagNames = tagIds.stream()
                        .map(tagId -> tagRepository.findById(tagId)
                                .map(Tag::getName)
                                .orElse("未知标签")) // 处理标签不存在的情况
                        .collect(Collectors.toList());

                // 拼接标签名称
                String tags = String.join(",", tagNames);
                row.createCell(6).setCellValue(tags);
            }

            // 自动调整列宽
            for (int i = 0; i < 7; i++) {
                sheet.autoSizeColumn(i);
            }

            workbook.write(out);
            return new ByteArrayResource(out.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException("导出Excel失败", e);
        }
    }

    // 导入增加标题和标签处理
    @Override
    @Transactional
    public List<Todo> importTodos(MultipartFile file, User user) {
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0);
            List<Todo> todos = new ArrayList<>();

            // 验证表头是否正确（与导出格式匹配）
            Row headerRow = sheet.getRow(0);
            if (headerRow == null || !isValidHeader(headerRow)) {
                throw new RuntimeException("导入文件格式错误，请使用系统导出的模板");
            }

            // 从第二行开始读取（跳过表头）
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                    continue;
                }

                // 验证行数据是否有效
                String title = getCellValue(row.getCell(0));
                String content = getCellValue(row.getCell(1));
                if (title == null || title.trim().isEmpty() ||
                        content == null || content.trim().isEmpty()) {
                    continue; // 跳过标题或内容为空的行
                }

                Todo todo = new Todo();
                // 修正列索引：严格对应导出的列顺序
                todo.setTitle(title);                  // 第0列：标题
                todo.setContent(content);              // 第1列：内容

                // 处理状态（第2列：状态）
                String statusStr = getCellValue(row.getCell(2));
                if (statusStr != null && !statusStr.isEmpty()) {
                    // 匹配导出的"已完成"/"待完成"文本
                    if ("已完成".equals(statusStr)) {
                        todo.setStatus(TodoStatus.completed);
                    } else {
                        todo.setStatus(TodoStatus.pending);
                    }
                } else {
                    todo.setStatus(TodoStatus.pending);
                }

                // 处理创建时间（第3列：创建时间）
                String createTimeStr = getCellValue(row.getCell(3));
                if (createTimeStr != null && !createTimeStr.isEmpty()) {
                    try {
                        LocalDateTime createTime = parseDateTime(createTimeStr);
                        todo.setCreatedAt(createTime);
                    } catch (DateTimeParseException e) {
                        // 解析失败则使用当前时间
                        todo.setCreatedAt(LocalDateTime.now());
                    }
                } else {
                    todo.setCreatedAt(LocalDateTime.now());
                }

                // 处理到期时间（第4列：到期时间）
                String deadlineStr = getCellValue(row.getCell(4));
                if (deadlineStr != null && !deadlineStr.isEmpty()) {
                    try {
                        LocalDateTime deadline = parseDateTime(deadlineStr);
                        todo.setDeadline(deadline);
                    } catch (DateTimeParseException e) {
                        // 忽略格式错误的日期，不设置到期时间
                    }
                }

                // 如果有标签列（根据实际导出格式调整索引）
                // String tagsStr = getCellValue(row.getCell(5)); // 如有标签列则启用

                todo.setUser(user);
                todos.add(todo);
            }

            return todoRepository.saveAll(todos);
        } catch (IOException e) {
            throw new RuntimeException("导入Excel失败", e);
        }
    }

    // 验证表头是否匹配导出格式
    private boolean isValidHeader(Row headerRow) {
        String[] expectedHeaders = {"标题", "内容", "状态", "创建时间", "到期时间"};
        for (int i = 0; i < expectedHeaders.length; i++) {
            Cell cell = headerRow.getCell(i);
            String headerValue = getCellValue(cell);
            if (!expectedHeaders[i].equals(headerValue)) {
                return false;
            }
        }
        return true;
    }

    // 解析多种格式的日期时间字符串
    private LocalDateTime parseDateTime(String dateStr) {
        // 支持的日期格式（与导出的格式匹配）
        String[] patterns = {
                "yyyy/M/d HH:mm:ss",
                "yyyy-MM-dd HH:mm:ss",
                "yyyy/MM/dd HH:mm:ss",
                "yyyy年MM月dd日 HH:mm:ss",
                "yyyy-MM-dd",
                "yyyy/MM/dd",
                "yyyy年MM月dd日",
                "MM/dd/yyyy",
                "dd-MM-yyyy"
        };

        for (String pattern : patterns) {
            try {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, Locale.CHINA);
                return LocalDateTime.parse(dateStr, formatter);
            } catch (DateTimeParseException e) {
                // 尝试下一种格式
                continue;
            }
        }

        // 如果所有格式都不匹配，尝试使用默认解析
        return LocalDateTime.parse(dateStr);
    }


    // 辅助方法：获取单元格值
    private String getCellValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }
}